﻿using Clancy.Common;
using Clancy.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Clancy.Bl.VideoProvider
{
    internal class VideoSourceFactory : IVideoSourceFactory, IDisposable
    {
        private readonly Dictionary<string, IVideoSourceHandler> m_VideoSources = new Dictionary<string, IVideoSourceHandler>();

        public void Dispose()
        {
            foreach (string videoSourceMoniker in m_VideoSources.Keys)
            {
                m_VideoSources[videoSourceMoniker].Close();
            }
            m_VideoSources.Clear();
        }

        public IVideoSourceHandler GetVideoSourceHandler(ISurveilanceObject surveilanceObject)
        {
            if (m_VideoSources.ContainsKey(surveilanceObject.MonikerString))
            {
                return m_VideoSources[surveilanceObject.MonikerString];
            }

            m_VideoSources[surveilanceObject.MonikerString] = CreateNewVideoSourceHandler(surveilanceObject);
            return m_VideoSources[surveilanceObject.MonikerString];
        }

        public void ReleaseVideoSource(IVideoSourceHandler videoSource)
        {
            string monikerString = m_VideoSources.Keys.FirstOrDefault(key => m_VideoSources.ContainsKey(key) && m_VideoSources[key] == videoSource);
            if (string.IsNullOrEmpty(monikerString))
                return;

            ReleaseVideoSource(monikerString);
        }

        public void ReleaseVideoSource(string monikerString)
        {
            if (!m_VideoSources.ContainsKey(monikerString))
                return;

            m_VideoSources[monikerString].Close();
            m_VideoSources.Remove(monikerString);
        }

        private static IVideoSourceHandler CreateNewVideoSourceHandler(ISurveilanceObject surveilanceObject)
        {
            IVideoSourceHandler videoSource;
            if (surveilanceObject.VideoSourceName == Constants.MjepSourceName)
            {
                videoSource = new MJpegVideoSourceHandler(surveilanceObject.MonikerString);
            }
            else if (surveilanceObject.VideoSourceName == Constants.FileSourceName)
            {
                videoSource = new FileVideoSourceHandler(surveilanceObject.MonikerString);
            }
            else
            {
                videoSource = new CaptureDeviceVideoSource(surveilanceObject.MonikerString);
            }
            return videoSource;
        }
    }
}